package structures;

import java.util.*;

/**
 * Maze: populated after the map is transmitted from the server.
 * Instantiated in the MapPacket constructor.
 * Use getInstance().
 * 
 * @author WHOMP
 * @since Java 1.6
 */
public class Maze {
	/*
	 * Static variables
	 */
	private static Maze m;
	static int numRows;
	static int numCols;
	static int numHome1;
	static int numJail1;
	static int numHome2;
	static int numJail2;
	static ArrayList<Cell> cells = new ArrayList<Cell>();
	
	// populated in Cell constructor
	static ArrayList<Position> home1Positions = 
		new ArrayList<Position>();
	static ArrayList<Position> jail1Positions = 
		new ArrayList<Position>();
	static ArrayList<Position> home2Positions = 
		new ArrayList<Position>();
	static ArrayList<Position> jail2Positions = 
		new ArrayList<Position>();
	
	// to be populated/updated upon cell updates
	static Position flag1Pos;
	static Position bomb1Pos;
	static Position flag2Pos;
	static Position bomb2Pos;
	
	
	/* Accessors */
	public static int getNumRows() { return numRows; }
	public static int getNumCols() { return numCols; }

	public static Position getFlag1Pos() { return flag1Pos; }
	public static Position getBomb1Pos() { return bomb1Pos; }
	public static Position getFlag2Pos() { return flag2Pos; }
	public static Position getBomb2Pos() { return bomb2Pos; }
	
	public static ArrayList<Cell> getCellsArrayList() { return cells; }
	
	public static ArrayList<Position> getHome1Positions() { return home1Positions; }
	public static ArrayList<Position> getJail1Positions() { return jail1Positions; }
	public static ArrayList<Position> getHome2Positions() { return home2Positions; }
	public static ArrayList<Position> getJail2Positions() { return jail2Positions; }
	
	/* Mutators */
	public static void setFlag1Pos(Position p) { flag1Pos = p; }
	public static void setBomb1Pos(Position p) { bomb1Pos = p; }
	public static void setFlag2Pos(Position p) { flag2Pos = p; }
	public static void setBomb2Pos(Position p) { bomb2Pos = p; }

	
	/*
	 *  Constructor ( 2 args )
	 */
	public Maze(int rows, int cols) {
		numRows = rows;
		numCols = cols;
	}

	
	/*
	 *  Constructor ( for client )
	 *  	Used once, upon receiving map packet.
	 */
	public Maze( int rows, int cols, int numHome1p, int numJail1p,
				int numHome2p, int numJail2p, char[] mapArray ) {
		// assign dimensions
		numRows = rows;
		numCols = cols;
		numHome1 = numHome1p;
		numJail1 = numJail1p;
		numHome2 = numHome2p;
		numJail2 = numJail2p;
		// populate cells structure
		for ( int i = 0; i < mapArray.length; i++ ) {
			Cell c = new Cell( i, mapArray[i], numCols );
			cells.add( c );
			//System.out.print(mapArray[i] +  c.getPosition().toString() );
		    //System.out.print(""+i+"["+((((i+1)/numCols)*numCols)-1)+"]");
			//if ( i == (((i+1)/numCols)*numCols)-1 ) 
				//System.out.println();
		}
		m = this;
	}
	
	/*
	 * Only 1 instance allowed
	 */
	public static Maze getInstance() {
		if ( m == null ) {
			throw new IllegalStateException("Maze should have been initialized in MapPacket.");
		}
		return m;
	}
	
	
	/*
	 * Accessors for a maze cell
	 */
	public Cell getCell( Position p ) {
		return cells.get(p.getIndex(numCols));
	}
	public Cell getCell( int r, int c ) {
		Position p = new Position( r,c );
		return getCell(p);
	}

	
}
